﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Batman.Cms.Core.Controllers;
using Batman.Cms.Core.Models.Mvc;
using Batman.Core.Models;
using Batman.Jianbei.Forum.Controllers.PumpSales.Filters;
using Batman.Jianbei.Forum.Controllers.PumpSales.Inputs;
using Batman.Jianbei.Forum.Controllers.PumpSales.Responses;
using Batman.Jianbei.Forum.Core.Domains.Dicts;
using Batman.Jianbei.Forum.Core.Domains.Pumps;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Omu.ValueInjecter;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Batman.Jianbei.Forum.Controllers.PumpSales
{
    [Authorize]
    public class PumpSaleInfoController : BatmanController<PumpSaleInfo>
    {
        public IRepository<PumpBrand, string> InsulinPumpRepo { get; set; }

        public IRepository<PumpModel, string> InsulinPumpModelRepo { get; set; }

        public IActionResult GetBrands()
        {
            var insulinPumpQuery = InsulinPumpRepo.GetAll().AsNoTracking();
            var insulinPumpModelQuery = InsulinPumpModelRepo.GetAll().AsNoTracking();

            var insulinBrandWithModelInfoList = insulinPumpQuery.GroupJoin(insulinPumpModelQuery, brand => brand.Id, model => model.PumpBrandId,
                (brand, model) => new NameValueChildrenDto<NameValueLinkDto>(brand.Name, brand.Id, model.Select(s => new NameValueLinkDto(s.Name, s.Id, s.PumpBrandId)).ToList()))
                .ToList();

            //var results = insulinBrandWithModelInfoList.GroupBy(t => new { t.BrandId, t.BrandName })
            //    .Select(t => new NameValueChildrenDto<NameValueLinkDto>(t.Key.BrandName, t.Key.BrandId, t.Select(s => new NameValueLinkDto(s.ModelName, s.ModelId, s.BrandId)).ToList()));

            return Json(insulinBrandWithModelInfoList);
        }

        /// <summary>
        /// 新建销售资料
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public IActionResult Create(PumpSaleInfoCreateInput model)
        {
            var result = BaseManager.Excute(repo =>
            {
                var query = repo.GetAll().AsNoTracking();

                var existing = query.Where(t => t.PumpNo == model.PumpNo).FirstOrDefault();

                if (existing != null)
                    return new ResponseBase(false, $"胰岛素泵编号已存在: {existing.PumpNo}");

                if (!InsulinPumpModelRepo.GetAll().AsNoTracking().Any(t => t.Id == model.PumpModelId))
                    return new ResponseBase(false, $"胰岛素泵型号不存在，请检查");

                var record = new PumpSaleInfo();
                record.InjectFrom(model);

                record.CreateBy = User.GetUserId();
                record.CreateAt = DateTime.Now;
                //record.PurchaseAt = DateTime.Now;
                record.CalWarranty(model.WarrantyEnd);

                repo.Insert(record);

                return new ResponseBase(true);

            });

            return Json(result);
        }

        /// <summary>
        /// 修改销售资料
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public IActionResult Update(PumpSaleInfoUpdateInput model)
        {
            var query = Reader.Repository.GetAll().AsNoTracking();
            var pumpSaleInfo = query.FirstOrDefault(t => t.Id == model.Id);

            if (pumpSaleInfo == null)
                return Json(new ResponseBase(false, "信息不存在,无法更新保存"));

            pumpSaleInfo.InjectFrom(model);

            pumpSaleInfo.CalWarranty(model.WarrantyEnd);


            var result = BaseManager.Excute(repo =>
            {
                repo.Update(pumpSaleInfo);
                return new ResponseBase(true);
            });

            return Json(result);
        }


        /// <summary>
        /// 获取胰岛素泵销售信息分页
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        public IActionResult GetPumpSaleInfos(PagedResultRequestDto page, PumpSaleInfoFilter filter)
        {
            var query = Reader.Repository.GetAll().AsNoTracking();

            if (!string.IsNullOrEmpty(filter.PhoneOrPumpNo))
                query = query.Where(t => t.Phone.Contains(filter.PhoneOrPumpNo) || t.PumpNo.Contains(filter.PhoneOrPumpNo));

            var total = query.Count();

            query = query.Include(t => t.PumpModel).ThenInclude(t => t.PumpBrand);

            query = query.OrderByDescending(t => t.CreateAt).Skip(page.SkipCount).Take(page.MaxResultCount).AsQueryable();

            var items = query.Select(t => new PumpSaleInfoResponse
            {
                Id = t.Id,
                CustomerName = t.CustomerName,
                PumpBrandId = t.PumpModel.PumpBrand.Id,
                PumpBrandName = t.PumpModel.PumpBrand.Name,
                PumpModelId = t.PumpModel.Id,
                PumpModelName = t.PumpModel.Name,
                Phone = t.Phone,
                PumpNo = t.PumpNo,
                CreateAt = t.CreateAt,
                PurchaseAt = t.PurchaseAt,
                WarrantyStart = t.WarrantyStart,
                WarrantyEnd = t.WarrantyEnd
            }).ToList();

            var result = new PagedResultDto<PumpSaleInfoResponse>(total, items);
            return Json(result);
        }

        /// <summary>
        /// 获取胰岛素泵销售信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IActionResult GetPumpSaleInfo(string id)
        {
            var query = Reader.Repository.GetAll().AsNoTracking();

            var pumpModel = query.Include(t => t.PumpModel).Where(t => t.Id == id).FirstOrDefault();

            if (pumpModel == null) return Json(new ResponseBase(false, "信息不存在或已删除"));

            return Json(new ResponseBase(true) { Result = pumpModel });
        }


        /// <summary>
        /// 批量删除（硬删除）
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public IActionResult Delete(List<string> ids)
        {
            if (ids != null)
            {
                BaseManager.Excute(repo =>
                {
                    repo.Delete(t => ids.Contains(t.Id));
                    return new ResponseBase(true);
                });
            }

            return Json(new ResponseBase(true));
        }
    }
}
